/**
 * @filename Main.java
 * @package top.h2v[tranformation]
 * @author Cdisk
 * @date 2012-11-20 上午10:20:00
 * @version v0.1
 */
package com.github.cdisk.xtrans.core;

import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.github.cdisk.xtrans.connect.Connect;

/**
 * @author 胡正衛
 */
public class Main extends Thread {

	private static final Logger LOGGER = Logger.getLogger(Main.class);
	private static final SimpleDateFormat YYMMDD_SDF = new SimpleDateFormat("yyyyMMdd");
	private static final SimpleDateFormat MM_SDF = new SimpleDateFormat("yyyyMM");
	private static final SimpleDateFormat HH_SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static final SimpleDateFormat HHMMSS_SDF = new SimpleDateFormat("HH:mm:ss");

	/** 转换文件对象 */
	private ConfigFile config;

	private Date startTime;

	public boolean isRun = true;


	public Main(ConfigFile config) {
		this.config = config;
		setName("MainRunner");
	}

	@Override
	public void run() {
		if (config.time != null || config.interval != null) {
			LOGGER.info("等待流程启动，预计启动时间：定时（" + config.time + "），间隔（" + config.interval + "）。");
		} else {
			LOGGER.info("等待流程启动......");
		}
		while (isRun) {
			if (runNow() || intervalTime() || runTime()) {
				LOGGER.info("开始执行处理文件...");
				startTime = new Date();

				int exec_index = -1;
				String exec_id = "";
				try {
					/* 从起点元素节点开始运行。 */
					for (int i = 0; i < config.beginnings.size(); i++) {
						BaseComponent component = config.beginnings.get(i);
						exec_index = i;
						exec_id = component.getId();
						if (component.isEnable()) { // 启用状态
							component.execute(null);
						}
					}
					Date date = new Date();
					long c = date.getTime() - startTime.getTime();
					writeLog("SUCCESS  执行时间:" + HH_SDF.format(startTime) + "-" + HH_SDF.format(date) + "(" + c/1000 + "." + c%1000 + "s)");
				} catch (Exception e) {
					LOGGER.error(e.getLocalizedMessage(), e);
					Date date = new Date();
					long c = date.getTime() - startTime.getTime();
					writeLog("FAILED  执行时间:" + HH_SDF.format(startTime) + "-" + HH_SDF.format(date) + "(" + c/1000 + "." + c%1000 + "s)" + "执行语句[" + exec_index + "]" + StringUtils.trimToEmpty(exec_id) + "时发生错误: " + e.getLocalizedMessage());
				} finally {
					/* 执行结束，关闭所有数据库连接。 */
					for (int i = 0; i < config.components.size(); i++) {
						Connect connect = config.components.get(i).connect;
						if (connect != null) {
							if (connect.getDb() != null) {
								connect.getDb().close();
							}
						}
					}
				}
				config.lasttime = new Date();
			}
			try { Thread.sleep(1000); } catch (InterruptedException e) {}
		}
	}

	/**
	 * 是否立即执行，如果立即执行，则只执行一次。
	 * @return
	 */
	private boolean runNow() {
		if (config.time == null && config.interval == null) {
			isRun = false;
			return true;
		}
		return false;
	}

	/**
	 * it's interval time!
	 * @return
	 */
	private boolean intervalTime() {
		if (config.interval == null) return false;
		long now = System.currentTimeMillis();
		long tag = config.lasttime == null ? 0 : (config.lasttime.getTime() + (Long.valueOf(config.interval) * 1000));
		return now > tag;
	}

	/**
	 * it's run time !
	 * @return
	 */
	public boolean runTime() {
		if (config.time == null) return false;
		String[] times = config.time.split(",");

		Date nowDate = new Date();

		boolean ok = false;
		for (String t : times) {
			int today = Integer.parseInt(YYMMDD_SDF.format(nowDate));
			int lastday = config.lasttime == null ? -1 : Integer.parseInt(YYMMDD_SDF.format(config.lasttime));

			int now = Integer.parseInt(HHMMSS_SDF.format(nowDate).replace(":", ""));
			int last = today != lastday ? -1 : config.lasttime == null ? -1 : Integer.parseInt(HHMMSS_SDF.format(config.lasttime).replace(":", ""));
			int time = Integer.parseInt(t.trim().replace(":", ""));
			
			ok |= now > time && last < time;
			if (ok) break;
		}
		return ok;
	}

	/**
	 * 写入执行日志
	 */
	private void writeLog(String message) {
		try {
			Date date = new Date();
			File file = new File(System.getProperty("user.dir") + "./logs/" + MM_SDF.format(date) + ".log");
			LOGGER.info(message);
			message = "[" + HH_SDF.format(date) + "]:  " + message + "\r\n";
			FileOutputStream out = new FileOutputStream(file, true);
			out.write(message.getBytes());
			out.close();
		} catch (Exception e) {
			LOGGER.error(e.getLocalizedMessage(), e);
		}
	}

}
